﻿using System;
using BattleCity.Classes;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BattleCity.GameObjects
{
    public class gBaseClass : DrawableGameComponent
    {
        const float FreeCollisionIndex = 2.0f;
        Texture2D _sprTexture;
        Rectangle _sprRectangle;
        //Прямоугольник, представляющий игровое окно
        Rectangle _scrBounds;
        float _depth;
        bool _isScreen, isAnim;

        protected AnimationPlayer _sprite;
        //Скорость объекта
        protected float _speed;

        public Vector2 SprPosition;
        public bool IsAlive { get; protected set; }

        public gBaseClass(Game game, Texture2D sprTexture, Vector2 sprPosition, Rectangle sprRectangle, float depth)
            : base(game)
        {
            _depth = depth;
            _sprTexture = sprTexture;
            SprPosition = sprPosition * 16;
            _sprRectangle = sprRectangle;
            _scrBounds = new Rectangle(0, 0, 416, 416);
        }
        public gBaseClass(Game game, Texture2D sprTexture, Rectangle sprRectangle, float depth)
            : base(game)
        {
            _depth = depth;
            _sprTexture = sprTexture;
            do
            {
                GetRandomPositionForBonus();
            } while (IsCollideWithNotBreakableObject());
            _sprRectangle = sprRectangle;
            _scrBounds = new Rectangle(0, 0, 416, 416);
        }
        public gBaseClass(Game game, ref Texture2D sprTexture, Vector2 sprPosition, Rectangle sprRectangle, float depth)
            : base(game)
        {
            _depth = depth;
            _sprTexture = sprTexture;
            SprPosition = sprPosition * 16;
            _sprRectangle = sprRectangle;
            _scrBounds = new Rectangle(0, 0, 416, 416);
        }
        public gBaseClass(Game game, ref AnimationPlayer spr, Vector2 sprPosition, Rectangle sprRectangle, float depth)
            : base(game)
        {
            _depth = depth;
            _sprite = spr;
            SprPosition = sprPosition * 16;
            _sprRectangle = sprRectangle;
            _scrBounds = new Rectangle(0, 0, 416, 416);
            isAnim = true;
        }
        public gBaseClass(Game game, ref AnimationPlayer spr, Rectangle sprRectangle, float depth)
            : base(game)
        {
            _depth = depth;
            _sprite = spr;
            _sprRectangle = sprRectangle;
            _scrBounds = new Rectangle(0, 0, 416, 416);
            isAnim = true;
        }
        public gBaseClass(Game game, bool scr)
            : base(game)
        {
            _depth = 1f;
            _sprRectangle = new Rectangle(0, 0, 480, 416);
            _scrBounds = new Rectangle(0, 0, 416, 416);
            _isScreen = scr;
        }

        void GetRandomPositionForBonus()
        {
            Random rand = new Random();
            SprPosition = new Vector2((float)rand.Next(0, 384), (float)rand.Next(0, 384));
        }
        public override void Initialize()
        {
            base.Initialize();
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            SpriteBatch sprBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            if (!_isScreen)
            {
                if (!isAnim)
                    sprBatch.Draw(_sprTexture, SprPosition, null, Color.White, 0f, new Vector2(0f, 0f), 1f, SpriteEffects.None, _depth);
                else
                    _sprite.Draw(gameTime, sprBatch, SprPosition, SpriteEffects.None, _depth);
            }
            base.Draw(gameTime);
        }
        //Проверка на столкновение с каким-либо объектом
        public bool IsCollideWithObject(gBaseClass spr)
        {
            if (spr.GetType() == (typeof(Enemy)) && (spr as Enemy)._iter <= 305)
                return false;
            else
                return (this.SprPosition.X + this._sprRectangle.Width > spr.SprPosition.X + FreeCollisionIndex &&
                        this.SprPosition.X < spr.SprPosition.X + spr._sprRectangle.Width - FreeCollisionIndex &&
                        this.SprPosition.Y + this._sprRectangle.Height > spr.SprPosition.Y + FreeCollisionIndex &&
                        this.SprPosition.Y < spr.SprPosition.Y + spr._sprRectangle.Height - FreeCollisionIndex);


        }
        //Процедуры для перемещения объекта
        public void MoveUp(float speed)
        {
            this.SprPosition.Y -= speed;
        }
        public void MoveDown(float speed)
        {
            this.SprPosition.Y += speed;
        }
        public void MoveLeft(float speed)
        {
            this.SprPosition.X -= speed;
        }
        public void MoveRight(float speed)
        {
            this.SprPosition.X += speed;
        }
        //Проверка на столкновение со стеной, камнем, водой или базой
        public bool IsCollideWithWall()
        {
            foreach (gBaseClass spr in Game.Components)
                if (spr.GetType() == (typeof(Wall)) || spr.GetType() == (typeof(Stone)) || spr.GetType() == (typeof(Water)) || spr.GetType() == (typeof(Base)) || spr.GetType() == (typeof(Enemy)))
                    if (IsCollideWithObject(spr)) return true;
            return false;
        }
        //Этот метод проверяет пересечение с неразрушаемым объектом (нужно для размещения бонуса)
        public bool IsCollideWithNotBreakableObject()
        {
            foreach (gBaseClass spr in Game.Components)
                if (spr.GetType() == (typeof(Stone)) || spr.GetType() == (typeof(Water)) || spr.GetType() == (typeof(Base)))
                    if (IsCollideWithObject(spr)) return true;
            return false;
        }
        //Проверка на столкновение со стеной, камнем, водой, базой или другим врагом
        public bool IsCollideWithWall(gBaseClass enemy)
        {
            foreach (gBaseClass spr in Game.Components)
                if (spr.GetType() == (typeof(Wall)) || spr.GetType() == (typeof(Stone)) || spr.GetType() == (typeof(Water)) || spr.GetType() == (typeof(Base)) || spr.GetType() == (typeof(Enemy)) || spr.GetType() == (typeof(Me)))
                    if (spr != enemy)
                        if (IsCollideWithObject(spr)) return true;
            return false;
        }
        //Проверка на столкновение с границами экрана
        public void Check()
        {
            if (SprPosition.X < _scrBounds.Left)
                SprPosition.X = _scrBounds.Left;
            if (SprPosition.X > _scrBounds.Width - _sprRectangle.Width)
                SprPosition.X = _scrBounds.Width - _sprRectangle.Width;
            if (SprPosition.Y < _scrBounds.Top)
                SprPosition.Y = _scrBounds.Top;
            if (SprPosition.Y > _scrBounds.Height - _sprRectangle.Height)
                SprPosition.Y = _scrBounds.Height - _sprRectangle.Height;
        }
        public bool CheckBounds()
        {
            return ((SprPosition.X < _scrBounds.Left |
                SprPosition.X > _scrBounds.Width - _sprRectangle.Width |
                SprPosition.Y < _scrBounds.Top |
                SprPosition.Y > _scrBounds.Height - _sprRectangle.Height));

        }
        public void Kill()
        {
            this.IsAlive = false;
        }
    }
}